/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package systole.domain.report.builder;

import com.itextpdf.text.BadElementException;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.MalformedURLException;
import systole.domain.analysis.Analysis;
import systole.domain.analysis.results.AnalysisResult;
import systole.domain.report.Report;
import systole.exceptions.ExceptionIO;
import systole.propertiesController.ReportSettingsProperties;

/**
 *
 * @author jmj
 */
public abstract class ReportBuilder {

    /**
     * Document to create
     */
    protected Document document;
    protected File file;
    protected String labelIAR = "Indice de Aumentación Radial:";
    protected String labelAOD = "Amplitud de Onda Diastólica:";
    protected String labelAOS = "Amplitud de Onda Sistólica:";
    protected ReportSettingsProperties reportSettingsProperties;

    /**
     * 
     */
    public ReportBuilder() {
        this.reportSettingsProperties = new ReportSettingsProperties();
    }

    /**
     * Method to build the report header in the document
     * @throws DocumentException
     * @throws IOException
     * @throws MalformedURLException
     */
    protected abstract void buildHeader() throws DocumentException, IOException, MalformedURLException;

    /**
     * Method to add patient info to document
     * 
     * @param analysis
     * @throws DocumentException 
     */
    protected abstract void buildPatientInfo(Analysis analysis) throws DocumentException;

    /**
     * Method to add report parameters to document 
     * 
     * @param analysis
     * @param report
     * @param analysisResult 
     * @throws DocumentException 
     */
    protected abstract void buildParamsInfo(Analysis analysis, Report report, AnalysisResult analysisResult) throws DocumentException;

    /**
     * Method to add plot image to document
     * 
     * @param image
     * @throws BadElementException 
     * @throws DocumentException
     * @throws IOException 
     */
    protected abstract void buildPlot(BufferedImage image) throws BadElementException, DocumentException, IOException;

    /**
     * @param analysis
     * @param report 
     * @throws DocumentException
     */
    protected abstract void buildConclusions(Analysis analysis, Report report) throws DocumentException;

    /**
     * Method to build the report
     * 
     * @param analysis
     * @param report
     * @param analysisResult
     * @param file
     */
    public void build(Analysis analysis, Report report, AnalysisResult analysisResult, File file) {
        try {
            this.file = file;
            this.createDocument();
            this.buildHeader();
            this.buildPatientInfo(analysis);
            this.buildParamsInfo(analysis, report, analysisResult);
            this.buildPlot(report.getGraphic());
            this.buildConclusions(analysis, report);
            this.closeDocument();
        } catch (DocumentException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Method to build the report for printer
     *
     * @param analysis
     * @param report
     * @param analysisResult
     * @return  file
     * @throws ExceptionIO
     */
    public File buildToPrint(Analysis analysis, Report report, AnalysisResult analysisResult) throws ExceptionIO {
        try {
            this.file = File.createTempFile("sysTemp", "tmp");
            this.build(analysis, report, analysisResult, file);
            return this.file;
        } catch (IOException ex) {
            ex.printStackTrace();
            return null;
        }
    }

    /**
     * Method to create document
     * @throws DocumentException
     * @throws FileNotFoundException
     * @throws IOException 
     */
    protected abstract void createDocument() throws DocumentException, FileNotFoundException, IOException;

    protected abstract void closeDocument();

    /**
     *
     * @param image
     * @param sizeIndex 0 -> 50*50 1-> 100*100 2->150*150
     * @return a image of size selected
     */
    protected Image scaleImage(Image image, int sizeIndex) {
        switch (sizeIndex) {
            case 1:
                image.scaleToFit(100, 100);
                break;
            case 2:
                image.scaleToFit(150, 150);
                break;
            default:
                image.scaleToFit(50, 50);
        }
        return image;
    }

    protected int getAmountOfIndex() {
        int amount = 0;
        amount += (this.reportSettingsProperties.loadUseAOD() ? 1 : 0);
        amount += (this.reportSettingsProperties.loadUseAOS() ? 1 : 0);
        amount += (this.reportSettingsProperties.loadUseFC() ? 1 : 0);
        amount += (this.reportSettingsProperties.loadUseIAR() ? 1 : 0);
        amount += (this.reportSettingsProperties.loadUseRS() ? 1 : 0);
        amount += (this.reportSettingsProperties.loadUseIMC() ? 1 : 0);
        return amount;
    }

    protected int getAmountOfData() {
        int amount = 0;
        amount += (this.reportSettingsProperties.loadUseAge() ? 1 : 0);
        amount += (this.reportSettingsProperties.loadUseHeight() ? 1 : 0);
        amount += (this.reportSettingsProperties.loadUseSmoke() ? 1 : 0);
        amount += (this.reportSettingsProperties.loadUseWeight() ? 1 : 0);
        amount += (this.reportSettingsProperties.loadUsePD() ? 1 : 0);
        amount += (this.reportSettingsProperties.loadUsePS() ? 1 : 0);
        return amount;
    }

    protected void writeEmptyLine() throws DocumentException{
        if (this.document!=null){
            this.document.add(new Paragraph(" "));
        }
    }
}
